package excel.imp;//package cn.xueden.common.core.excel.imp;
//
//
//import cn.xueden.common.core.context.ContextHolder;
//import cn.xueden.common.core.context.TaskContext;
//import cn.xueden.common.core.excel.annotation.ExcelExistValid;
//import cn.xueden.common.core.excel.annotation.ExcelLengthValid;
//import cn.xueden.common.core.excel.annotation.ExcelPatternValid;
//import cn.xueden.common.core.excel.annotation.ExcelRangeValid;
//import cn.xueden.common.core.excel.res.ExcelErrMsgRes;
//import cn.xueden.common.core.excel.res.ImportRes;
//import cn.xueden.common.core.excel.task.AbstractDefaultTask;
//import cn.xueden.common.core.excel.task.TaskVO;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.lang3.ObjectUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//
//import java.io.File;
//import java.io.IOException;
//import java.io.InputStream;
//import java.io.Serializable;
//import java.lang.reflect.Field;
//import java.math.BigDecimal;
//import java.math.BigInteger;
//import java.nio.file.Files;
//import java.util.ArrayList;
//import java.util.Collections;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//import java.util.Objects;
//
//@Slf4j
//@Component
//public abstract class ImportTemple<T extends Serializable> extends AbstractDefaultTask<String, ExcelImpReq> {
//
//    protected static final ThreadLocal<Map<String, Object>> threadLocal = new ThreadLocal<>();
//
//    private static final String TASK = "task";
//
//    private static final String RES = "res";
//
//    private static final String PARAM_JSON = "paramJson";
//
//    @Autowired
//    private ImpTypeConfig config;
//
//    @Override
//    public String execute(ExcelImpReq dto) {
//        Long taskId = dto.getId();
//        ImpType impType = config.getTypeMap().get(dto.getType());
//        TaskVO<Void> taskVO = new TaskVO<>();
//        taskVO.setTaskId(taskId);
//        taskVO.setTaskName(impType.getTaskName() + "_" + taskId);
//        taskVO.setSerialNo(impType.getSerialNo() + "_" + taskId);
//        taskVO.setBizType(ObjectUtils.isNotEmpty(impType.getBizType()) ? impType.getBizType() : 0);
//        taskVO.setTaskSource(ObjectUtils.isNotEmpty(impType.getTaskSource()) ? impType.getTaskSource() : 0);
//        Map<String, Object> map = new HashMap<>();
//        map.put(TASK, taskVO);
//        ImportRes res = new ImportRes();
//        map.put(RES, res);
//        map.put(PARAM_JSON, dto.getParamJson());
//        threadLocal.set(map);
//        TaskContext taskContext = new TaskContext(ContextHolder.get(), taskVO);
//        InputStream inputStream = null;
//        try {
//            working(taskContext);
//            inputStream = CommonFileUtil.getHttpOssFile(dto.getFileName());
//            EasyExcel.read(inputStream, ClassUtil.getActualTypeArgument(this.getClass()),
//                    new ExcelCommonListener<>(config.getBatchCount(), this)).sheet()
//                .headRowNumber(Objects.isNull(impType.getHeadRowNumber()) ? 0 : impType.getHeadRowNumber()).doRead();
//            success(taskContext,
//                taskVO.getTaskName() + "完成,成功导入" + res.getSuccessCount() + "条,失败" + res.getFailCount() + "条",
//                uploadErrDetails(res.getErrDetails()));
//        } catch (Exception e) {
//            log.error(taskVO.getTaskName() + "失败！异常信息如下: ", e);
//            taskDetail(taskVO.getTaskId(), taskVO.getTaskName() + "失败；异常信息:" + e.getMessage());
//            fail(taskContext, taskVO.getTaskName() + "失败");
//        } finally {
//            threadLocal.remove();
//            if (Objects.nonNull(inputStream)) {
//                try {
//                    inputStream.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//        return null;
//    }
//
//    public String uploadErrDetails(List<List<String>> errDetails) {
//        String url = null;
//        if (CollUtil.isEmpty(errDetails)) {
//            return url;
//        }
//        ExcelWriter excelWriter = null;
//        File file = null;
//        //设置导出的数据内容
//        try {
//            String taskName = ((TaskVO<?>)threadLocal.get().get(TASK)).getTaskName();
//            StringBuilder fileRootDir =
//                new StringBuilder(FileConstant.SAVE_PATH).append(File.separator).append("excel").append(File.separator)
//                    .append("import").append(File.separator).append("errMsg").append(File.separator);
//            File fileDir = new File(fileRootDir.toString());
//            if (!fileDir.exists() && !fileDir.mkdirs()) {
//                log.error("任务：{}，创建文件夹{}失败", taskName, fileRootDir);
//                throw new BizException(Constants.MSG_BIZ_FAIL);
//            }
//            String fileName = taskName + "失败数据";
//            String filePath = fileRootDir.append(fileName).append(".xlsx").toString();
//            file = new File(filePath);
//            if (!file.exists() && !file.createNewFile()) {
//                log.error("任务：{}，创建文件{}失败", taskName, filePath);
//                throw new BizException(Constants.MSG_BIZ_FAIL);
//            }
//            // 创建ExcelWriter对象
//            excelWriter = EasyExcel.write(filePath).build();
//            ExcelWriterSheetBuilder sheetBuilder = EasyExcel.writerSheet(0, taskName);
//            List<List<String>> head = createErrHead(taskName);
//            if (CollUtil.isNotEmpty(head)) {
//                sheetBuilder.head(head);
//            }
//            WriteSheet writeSheet = sheetBuilder.build();
//            excelWriter.write(errDetails, writeSheet);
//            excelWriter.finish();
//            // 上传文件
//            try {
//                //阿里云返回url
//                url = OssUpload.upload(filePath, fileName);
//            } catch (Exception e1) {
//                log.error("写入数据到Excel的过程中或者上传到阿里云中发生错误", e1);
//            }
//        } catch (Exception e) {
//            log.error("写入数据到Excel的过程中或者上传到阿里云中发生错误", e);
//        } finally {
//            if (excelWriter != null) {
//                excelWriter.finish();
//            }
//            if (file != null) {
//                try {
//                    Files.delete(file.toPath());
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//        return url;
//    }
//
//    public List<List<String>> createErrHead(String fileName) {
//        // 具体行数
//        List<List<String>> heads = new ArrayList<>();
//        for (Field field : ClassUtil.listAllField(ClassUtil.getActualTypeArgument(this.getClass()))) {
//            if ("serialVersionUID".equals(field.getName())) {
//                continue;
//            }
//            // 设置可访问
//            field.setAccessible(true);
//            // 非空参数校验
//            // 字段是否引用注解
//            boolean isValid = field.isAnnotationPresent(ExcelProperty.class);
//            if (!isValid) {
//                return Collections.emptyList();
//            }
//            String[] value1 = field.getAnnotation(ExcelProperty.class).value();
//            if (ArrayUtil.isEmpty(value1)) {
//                return Collections.emptyList();
//            }
//            List<String> head = new ArrayList<>();
//            head.add(fileName);
//            head.add(value1[value1.length - 1]);
//            heads.add(head);
//        }
//        List<String> head = new ArrayList<>();
//        head.add(fileName);
//        head.add("错误详情");
//        heads.add(head);
//        return heads;
//    }
//
//    public void exception(ExcelErrMsgRes<T> res) {
//        exception(res.getMsg(), res.getData());
//    }
//
//    public void exception(String errMsg, T data) {
//        TaskVO<?> taskVO = (TaskVO<?>)threadLocal.get().get(TASK);
//        log.error("{}异常,信息如下：{}", taskVO.getTaskName(), errMsg);
//        taskDetail(taskVO.getTaskId(), errMsg);
//        ImportRes res = (ImportRes)threadLocal.get().get(RES);
//        List<String> list;
//        if (Objects.nonNull(data)) {
//            list = BeanUtils.bean2StringList(data);
//        } else {
//            list = BeanUtils.bean2StringList(ClassUtil.getActualTypeArgument(this.getClass()));
//        }
//        list.add(errMsg);
//        res.addErrDetails(list);
//    }
//
//    /**
//     * 执行业务逻辑
//     *
//     * @param dataList 导入的数据
//     */
//    public void executeData(List<T> dataList) {
//        TaskVO<?> taskVO = (TaskVO<?>)threadLocal.get().get(TASK);
//        ImportRes res = (ImportRes)threadLocal.get().get(RES);
//        if (CollUtil.isEmpty(dataList)) {
//            return;
//        }
//        log.info("执行{}数据size={}", taskVO.getTaskName(), dataList.size());
//        try {
//            Object o = threadLocal.get().get(PARAM_JSON);
//            Integer sucCnt;
//            if (Objects.isNull(o)) {
//                sucCnt = saveOrUpdate(dataList);
//            } else {
//                sucCnt = saveOrUpdate(new SaveWithParamDTO<>(dataList, o.toString()));
//            }
//            res.addSuccessCount(sucCnt);
//            res.addFailCount(dataList.size() - sucCnt);
//        } catch (Exception e) {
//            log.error("{}批量导入失败，异常原因：", taskVO.getTaskName(), e);
//            res.addFailCount(dataList.size());
//            taskDetail(taskVO.getTaskId(), taskVO.getTaskName() + "批量导入失败，异常原因：" + e.getMessage());
//        }
//    }
//
//    /**
//     * 批量入库具体实现类(不带paramJson)（两个saveOrUpdate二选一，没有paramJson就实现这个，另一个直接返回0）
//     *
//     * @param dataList 数据列表
//     * @return Integer
//     * @author Gxr
//     * @since 2024/3/29 16:15
//     */
//    public Integer saveOrUpdate(List<T> dataList) {
//        return 0;
//    }
//
//    /**
//     * 批量入库具体实现类(带paramJson)（两个saveOrUpdate二选一，有paramJson就实现这个，需将paramJson转换成自己需要的入参对象，另一个直接返回0）
//     *
//     * @param dto 带参数导入excel dto
//     * @return Integer
//     * @author Gxr
//     * @since 2024/3/29 16:16
//     */
//    public Integer saveOrUpdate(SaveWithParamDTO<T> dto) {
//        return 0;
//    }
//
//    public boolean valid(T data, AnalysisContext analysisContext) {
//        Field[] fields = data.getClass().getDeclaredFields();
//        // 具体行数
//        Integer rowIndex = analysisContext.readRowHolder().getRowIndex();
//        int index = 0;
//        boolean res = true;
//        for (Field field : fields) {
//            int colIndex;
//            String excelPropertyName;
//            // 具体文件字段
//            if (field.isAnnotationPresent(ExcelProperty.class)) {
//                ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
//                colIndex = excelProperty.index();
//                if (-1 == colIndex) {
//                    colIndex = index;
//                }
//                excelPropertyName = excelProperty.value()[excelProperty.value().length - 1];
//            } else {
//                colIndex = index;
//                excelPropertyName = StrUtil.EMPTY;
//            }
//
//            // 设置可访问
//            field.setAccessible(true);
//            // 非空参数校验
//            if (!checkExist(field, data, rowIndex, colIndex, excelPropertyName) || !checkPattern(field, data, rowIndex,
//                colIndex, excelPropertyName) || !checkLength(field, data, rowIndex, colIndex,
//                excelPropertyName) || !checkRange(field, data, rowIndex, colIndex, excelPropertyName)) {
//                res = false;
//            }
//            index++;
//        }
//        if (!checkPeculiar(data, rowIndex)) {
//            res = false;
//        }
//        if (!res) {
//            ((ImportRes)threadLocal.get().get(RES)).addFailCount();
//        }
//        return res;
//    }
//
//    /**
//     * 非空校验
//     *
//     * @param field    字段
//     * @param data     当前行的数据
//     * @param rowIndex 行号
//     * @param colIndex 列号
//     * @param key      标题
//     * @return 是否通过校验
//     */
//    public boolean checkExist(Field field, T data, Integer rowIndex, int colIndex, String key) {
//        // 字段是否引用注解
//        boolean isValid = field.isAnnotationPresent(ExcelExistValid.class);
//        if (isValid) {
//            Object value;
//            try {
//                value = field.get(data);
//            } catch (IllegalAccessException e) {
//                exception(createReadExcMsg(rowIndex, colIndex, key), data);
//                return false;
//            }
//            if (Objects.isNull(value) || value instanceof String && StrUtil.isEmpty((String)value)) {
//                exception(
//                    getRowColIndex(rowIndex, colIndex, key) + field.getAnnotation(ExcelExistValid.class).message(),
//                    data);
//                return false;
//            }
//        }
//        return true;
//    }
//
//    /**
//     * 正则校验
//     *
//     * @param field    字段
//     * @param data     当前行的数据
//     * @param rowIndex 行号
//     * @param colIndex 列号
//     * @param key      标题
//     * @return 是否通过校验
//     */
//    public boolean checkPattern(Field field, T data, Integer rowIndex, int colIndex, String key) {
//        // 字段是否引用注解
//        boolean isValid = field.isAnnotationPresent(ExcelPatternValid.class);
//        if (isValid) {
//            ExcelPatternValid patternValid = field.getAnnotation(ExcelPatternValid.class);
//            String value;
//            try {
//                value = (String)field.get(data);
//            } catch (IllegalAccessException e) {
//                exception(createReadExcMsg(rowIndex, colIndex, key), data);
//                return false;
//            }
//            if (StrUtil.isNotBlank(value) && !ReUtil.isMatch(patternValid.value().getPattern(), value)) {
//                exception(getRowColIndex(rowIndex, colIndex, key) + (StrUtil.isEmpty(patternValid.message())
//                    ? patternValid.value().getMessage() : patternValid.message()), data);
//                return false;
//            }
//        }
//        return true;
//    }
//
//    /**
//     * 字符串长度校验
//     *
//     * @param field    字段
//     * @param data     当前行的数据
//     * @param rowIndex 行号
//     * @param colIndex 列号
//     * @param key      标题
//     * @return 是否通过校验
//     */
//    public boolean checkLength(Field field, T data, Integer rowIndex, int colIndex, String key) {
//        // 字段是否引用注解
//        boolean isValid = field.isAnnotationPresent(ExcelLengthValid.class);
//        if (isValid) {
//            ExcelLengthValid lengthValid = field.getAnnotation(ExcelLengthValid.class);
//            String value;
//            try {
//                value = (String)field.get(data);
//            } catch (IllegalAccessException e) {
//                exception(createReadExcMsg(rowIndex, colIndex, key), data);
//                return false;
//            }
//            if (StrUtil.isNotBlank(
//                value) && (lengthValid.max() < value.length() || lengthValid.min() > value.length())) {
//                exception(getRowColIndex(rowIndex, colIndex, key) + lengthValid.message(), data);
//                return false;
//            }
//        }
//        return true;
//    }
//
//    /**
//     * 数字大小校验
//     *
//     * @param field    字段
//     * @param data     当前行的数据
//     * @param rowIndex 行号
//     * @param colIndex 列号
//     * @param key      标题
//     * @return 是否通过校验
//     */
//    public boolean checkRange(Field field, T data, Integer rowIndex, int colIndex, String key) {
//        // 字段是否引用注解
//        boolean isValid = field.isAnnotationPresent(ExcelRangeValid.class);
//        if (isValid) {
//            ExcelRangeValid rangeValid = field.getAnnotation(ExcelRangeValid.class);
//            Object value;
//            try {
//                value = field.get(data);
//            } catch (IllegalAccessException e) {
//                exception(createReadExcMsg(rowIndex, colIndex, key), data);
//                return false;
//            }
//            if (Objects.isNull(value)) {
//                return true;
//            }
//            if (!(value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long || value instanceof Double || value instanceof Float || value instanceof BigDecimal || value instanceof BigInteger) && !ReUtil.isMatch(
//                ExcelValidEnum.NUMBERS.getPattern(), (String)value)) {
//                return true;
//            }
//            int comparisonMaxResult = new BigDecimal(value.toString()).compareTo(new BigDecimal(rangeValid.max()));
//            int comparisonMinResult = new BigDecimal(value.toString()).compareTo(new BigDecimal(rangeValid.min()));
//            return rangeValid.inclusive() ? comparisonMaxResult <= 0 && comparisonMinResult >= 0
//                : comparisonMaxResult < 0 && comparisonMinResult > 0;
//        }
//        return true;
//    }
//
//    public String getRowColIndex(Integer rowIndex, int colIndex, String key) {
//        return "第" + (rowIndex + 1) + "行第" + (colIndex + 1) + "列[" + key + "]";
//    }
//
//    public String createReadExcMsg(Integer rowIndex, int colIndex, String key) {
//        return getRowColIndex(rowIndex, colIndex, key) + "读取数据异常";
//    }
//
//    /**
//     * 业务特殊校验
//     *
//     * @return 是否通过校验
//     */
//    public boolean checkPeculiar(T data, Integer rowIndex) {
//        return true;
//    }
//
//}
